package com;

/**
 * 内部类
 * 1.成员内部类：直接再类中定义的类
 * 2.方法内部类：在一个类中的方法内定义一个类
 *      （1）方法内部类只能定义该内部类的方法内实例，不可以在此方法外对其实例化
 *      （2）方法内部类对象不能使用该内部类所在方法的非final局部变量
 * 3.静态内部类：在一个内部定义一个静态内部类，静态的含义是该内部类可以像其他静态成员一样，没有外部类对象时，也能够访问它，静态嵌套
 * 类仅能访问外部类的静态成员和方法
 *
 * 局部内部类访问局部变量必须使用final修饰，为什么？
 * 当调用这个方法时，局部变量如果没有final修饰，他的生命周期和方法的生命周期是一样的，当方法被调入时会入栈，方法结束后即弹栈，
 * 这个局部变量也会消失，那么如果局部内部类对象还没有马上消失想用这个局部变量，显然已无法使用了，如果用final修饰会在类加载时候进入常量池，
 * 即时方法弹栈，常量池的常量还在 ，也就可以继续使用了
 * 注意：在jdk1.8中取消了在局部内部类中使用的变量必须显示的使用final修饰，编译器默认会为这个比哪里加上final。
 *
 *
 * 内部类的作用：
 *  每个内部类都能独立地继承自一个接口的实现，
 *  所以无论外部类是否已经继承了某个（接口的）实现，对于内部类都没有影响。如果没有内部类提供的可以继承多个具体的或抽象的类的能力
 *  一些设计与编程问题就很难解决，从这个角度看，内部类使得多重继承的解决方案变得完整，接口解决了部分问题，而内部类有效地实现了”多重继承"
 */
public class InnerClass {
    public static void main(String[] args) {
        Outer outer=new Outer();
       outer.innerPrint();
       outer.Show();
    }
}
//--------成员内部类--------------
class Outer{
    private String name;
    //建议在外部类中定义一个方法,对外提供访问内部类的接口
    public void innerPrint(){
        Inner inner=new Inner();
        inner.print();
    }
   private class Inner{
        public void print(){
            System.out.println("inner");
        }
    }
    //----------方法内部类-------------------
    public void Show(){
       final  int x=1111;//show方法的局部变量或方法的参数，实际必须是常量final
        class Inner2{
            public void print(){
                //从内部类中引用本地变量必须时最终变量或实际上的最终变量
                System.out.println("方法内部类,变量值为："+x);
            }
        }
        Inner2 inner2=new Inner2();
        inner2.print();
    }
}
